package com.ichoice.rabbitmq.rpc.helper.sub;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ichoice.hsp.cache.utils.RedisUtil;
import com.ichoice.rabbitmq.rpc.helper.model.SubScribeModel;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 缓存订阅关系类
 *
 * @author xianrensawang
 * @date 2021/3/11
 */
public final class SubScribeStoreHelper {

    private static final String FANOUT_PRE = "HSP_RABBITMQ_RPC_HELP:";

    private SubScribeStoreHelper() {

    }

    private static final ConcurrentHashMap<String, Map<String, SubScribeModel>> CACHE = new ConcurrentHashMap<>();

    private static final ConcurrentHashMap<String, Integer> CACHE_FLAG = new ConcurrentHashMap<>();

    /**
     * 缓存订阅关系
     *
     * @param scribeModel 订阅信息
     */
    public static void store(SubScribeModel scribeModel) {
        String key = scribeModel.getServerBean() + "-" + scribeModel.getServerMethod();
        String mapKey = scribeModel.getClientName();
        if (CACHE.containsKey(key)) {
            Map<String, SubScribeModel> scribeModelMap = CACHE.get(key);
            scribeModelMap.put(mapKey, scribeModel);
        } else {
            Map<String, SubScribeModel> scribeModelMap = new HashMap<>();
            scribeModelMap.put(mapKey, scribeModel);
            CACHE.put(key, scribeModelMap);
        }
        String redisKey = generateRedisKey(key, mapKey);
        RedisUtil.set(redisKey, JSON.toJSONString(scribeModel));
    }

    /**
     * 移除订阅关系
     *
     * @param scribeModel 订阅信息
     */
    public static void remove(SubScribeModel scribeModel) {
        String key = scribeModel.getServerBean() + "-" + scribeModel.getServerMethod();
        String mapKey = scribeModel.getClientName();
        Map<String, SubScribeModel> scribeModelMap = CACHE.get(key);
        if (Objects.nonNull(scribeModelMap)) {
            scribeModelMap.remove(mapKey);
        }
        String redisKey = generateRedisKey(key, mapKey);
        RedisUtil.del(redisKey);
    }

    /**
     * 获取缓存关系map
     *
     * @param key 关系key
     * @return 关系map
     */
    public static Map<String, SubScribeModel> get(String key) {
        if (CACHE_FLAG.containsKey(key)) {
            return CACHE.get(key);
        }
        Map<String, SubScribeModel> modelMap = new HashMap<>();
        String redisKey = generateRedisKey(key, "*");
        Set<String> keys = RedisUtil.getKeys(redisKey);
        for (String s : keys) {
            Object o = RedisUtil.get(s);
            SubScribeModel model = JSONObject.parseObject(o.toString(), SubScribeModel.class);
            String clientName = getClientByKey(s);
            modelMap.put(clientName, model);
        }
        CACHE.put(key, modelMap);
        CACHE_FLAG.put(key, 1);
        return modelMap;
    }

    public static ConcurrentHashMap<String, Map<String, SubScribeModel>> getAll() {
        return CACHE;
    }


    private static String generateRedisKey(String key, String mapKey) {
        return FANOUT_PRE + key + ":" + mapKey;
    }


    private static String getClientByKey(String key) {
        String[] split = key.split(":");
        return split.length > 0 ? split[split.length - 1] : "";
    }

}
